package com.cc.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component
@Aspect//定义切面
public class AppAspect {
    //切面=切点(需要增强的那个方法)+增强/通知
    //方法定义：public int add(int a,int b);
    @Pointcut("execution(* com.cc.dao.UserDaoImpl.add(..))")
    public void pointCutAdd() {}
    
    ///////////////////////////////一、前置通知//////////
    
    @Pointcut("execution(* com.cc.dao.UserDaoImpl.update(..))")
    public void pointCutUpdate() {}
    //1.1.前置通知/增强
    @Before("pointCutAdd()")   
    public void before(JoinPoint joinPoint) {
        System.out.println("鉴权...."+joinPoint.getArgs()[0]+"\t"+joinPoint.getArgs()[1]);
    }
  //1.2.前置通知/增强  ：方法执行前先执行前置通知的代码
    @Before("execution(* com.cc.dao.UserDaoImpl.delete(..))")   
    public void before2() {
        System.out.println("参数校验....");
    }
    
  //1.3.前置通知/增强
    @Before("pointCutAdd()  ||  pointCutUpdate() ")   
    public void before3(JoinPoint joinPoint) {
        System.out.println("参数校验 & 鉴权....");
    }
    ///////////////////////////////二、后置通知:方法正常返回的时候//////////
    @AfterReturning(value="execution(*  com.cc.dao.UserDaoImpl.add(..))",returning="result")
    public void AfterReturning(JoinPoint joinPoint,Object result) {
       System.out.println("后置通知执行了....,方法 的返回值为："+result);
    }
    ///////////////////////////////三、最终通知：方法退出的时候//////////
    @After("execution(*  com.cc.dao.UserDaoImpl.add(..))")
    public void After(JoinPoint joinPoint) {
        System.out.println("最终通知执行了....");
    }
    ///////////////////////////////四、环绕通知：方法执行过程中//////////
    @Around("execution(*  com.cc.dao.UserDaoImpl.add(..))")
    public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
        Object[] args = pjp.getArgs();
        args[0]=100;
        args[1]=2;
        // start stopwatch
        Object retVal = pjp.proceed(args);//调用目标方法
        // stop stopwatch
        System.out.println("方法返回值为："+retVal);
        return retVal;
    }
///////////////////////////////五、异常通知：方法异常退出的时候//////////
    @AfterThrowing("execution(*  com.cc.dao.UserDaoImpl.add(..))")
    public void doRecoveryActions(JoinPoint joinPoint) {
        System.out.println("异常通知执行了.... :切点："+joinPoint.getSignature()+"\t参数为："+joinPoint.getArgs());
    }
}
